home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / tde3.zip / CFGFILE.C < prev    next >
C/C++ Source or Header  |  1993-06-05  |  32KB  |  939 lines

  1. /*
  2.  * This module contains all the routines needed to redefine key, colors, and
  3.  *   modes via a configuration file.
  4.  *
  5.  * Program Name:  tdecfg
  6.  * Author:        Frank Davis
  7.  * Date:          June 5, 1992
  8.  */
  9.  
  10.  
  11. #include <io.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. #include "tdecfg.h"
  17. #include "cfgfile.h"
  18.  
  19.  
  20. /*
  21.  * reference the structures in config files.
  22.  */
  23. extern struct vcfg cfg;
  24. extern FILE *tde_exe;                  /* FILE pointer to tde.exe */
  25. extern KEY_FUNC key_func;
  26. extern MACRO macros;
  27. extern COLORS temp_colours;
  28. extern MODE_INFO in_modes;
  29. extern long keys_offset;
  30. extern long two_key_offset;
  31. extern long macro_offset;
  32. extern long color_offset;
  33. extern long mode_offset;
  34. extern long sort_offset;
  35.  
  36.  
  37.  
  38. char line_in[2000];             /* line buffer */
  39. int  stroke_count;              /* global variable for macro strokes */
  40. unsigned int line_no;           /* global variable for line count */
  41. int modes[NUM_MODES];
  42.  
  43.  
  44. TWO_KEY two_key_list;
  45.  
  46. SORT_ORDER sort_order;
  47.  
  48.  
  49. /*
  50.  * Name:    tdecfgfile
  51.  * Date:    June 5, 1992
  52.  * Notes:   read in a configuration file
  53.  */
  54. void tdecfgfile( void )
  55. {
  56. FILE *config;
  57. char fname[80];
  58. int  rc;
  59.  
  60.    /*
  61.     * prompt for the configuration file name.
  62.     */
  63.    cls( );
  64.    xygoto( 0, 3 );
  65.    puts( "Enter configuration file name, e.g. tde.cfg  :" );
  66.    gets( fname );
  67.  
  68.    if (strlen( fname ) != 0) {
  69.       rc = OK;
  70.       if ((rc = access( fname, EXIST )) != 0) {
  71.          puts( "\n\n Error: File not found." );
  72.          getkey( );
  73.          rc = ERROR;
  74.       } else if ((config = fopen( fname, "r" )) == NULL ) {
  75.          puts( "\n\nError: Cannot open configuration file." );
  76.          getkey( );
  77.          rc = ERROR;
  78.       }
  79.  
  80.       /*
  81.        * if everything is everthing so far, get the current editor settings.
  82.        */
  83.       if (rc == OK) {
  84.          fseek( tde_exe, keys_offset, SEEK_SET );
  85.          fread( (void *)&key_func, sizeof(KEY_FUNC), 1, tde_exe );
  86.          fseek( tde_exe, two_key_offset, SEEK_SET );
  87.          fread( (void *)&two_key_list, sizeof(TWO_KEY), 1, tde_exe );
  88.          fseek( tde_exe, macro_offset, SEEK_SET );
  89.          fread( (void *)¯os, sizeof(MACRO), 1, tde_exe );
  90.          fseek( tde_exe, color_offset, SEEK_SET );
  91.          fread( (void *)&temp_colours, sizeof(COLORS), 1, tde_exe );
  92.          fseek( tde_exe, mode_offset, SEEK_SET );
  93.          fread( (void *)&in_modes, sizeof( MODE_INFO ), 1, tde_exe );
  94.          fseek( tde_exe, sort_offset, SEEK_SET );
  95.          fread( (void *)&sort_order, sizeof( SORT_ORDER ), 1, tde_exe );
  96.  
  97.          stroke_count = get_stroke_count( );
  98.  
  99.          /*
  100.           * put the current modes into an array.  it's easier to work
  101.           *   with them in an array.  This is from cfgmode.c.
  102.           */
  103.          modes[Ins]         = in_modes.insert;
  104.          modes[Ind]         = in_modes.indent;
  105.          modes[PTAB]        = in_modes.ptab_size;
  106.          modes[LTAB]        = in_modes.ltab_size;
  107.          modes[Smart]       = in_modes.smart_tab;
  108.          modes[Write_Z]     = in_modes.control_z;
  109.          modes[Crlf]        = in_modes.crlf;
  110.          modes[Trim]        = in_modes.trailing;
  111.          modes[Eol]         = in_modes.show_eol;
  112.          modes[WW]          = in_modes.word_wrap;
  113.          modes[Left]        = in_modes.left_margin;
  114.          modes[Para]        = in_modes.parg_margin;
  115.          modes[Right]       = in_modes.right_margin;
  116.          modes[Size]        = in_modes.cursor_size;
  117.          modes[Backup]      = in_modes.do_backups;
  118.          modes[Ruler]       = in_modes.ruler;
  119.          modes[Date]        = in_modes.date_style;
  120.          modes[Time]        = in_modes.time_style;
  121.          modes[InflateTabs] = in_modes.inflate_tabs;
  122.          modes[Initcase]    = in_modes.search_case;
  123.          modes[JustRM]      = in_modes.right_justify;
  124.  
  125.          line_no = 1;
  126.          while (!feof( config )) {
  127.             if (fgets( line_in, 1500, config ) == NULL)
  128.                break;
  129.             parse_line( line_in );
  130.             ++line_no;
  131.          }
  132.  
  133.          /*
  134.           *  if we changed any modes, reset them b4 we write them to tde.exe.
  135.           */
  136.          in_modes.insert        = modes[Ins];
  137.          in_modes.indent        = modes[Ind];
  138.          in_modes.ptab_size     = modes[PTAB];
  139.          in_modes.ltab_size     = modes[LTAB];
  140.          in_modes.smart_tab     = modes[Smart];
  141.          in_modes.control_z     = modes[Write_Z];
  142.          in_modes.crlf          = modes[Crlf];
  143.          in_modes.trailing      = modes[Trim];
  144.          in_modes.show_eol      = modes[Eol];
  145.          in_modes.word_wrap     = modes[WW];
  146.          in_modes.left_margin   = modes[Left];
  147.          in_modes.parg_margin   = modes[Para];
  148.          in_modes.right_margin  = modes[Right];
  149.          in_modes.cursor_size   = modes[Size];
  150.          in_modes.do_backups    = modes[Backup];
  151.          in_modes.ruler         = modes[Ruler];
  152.          in_modes.date_style    = modes[Date];
  153.          in_modes.time_style    = modes[Time];
  154.          in_modes.inflate_tabs  = modes[InflateTabs];
  155.          in_modes.search_case   = modes[Initcase];
  156.          in_modes.right_justify = modes[JustRM];
  157.  
  158.          fseek( tde_exe, keys_offset, SEEK_SET );
  159.          fwrite( (void *)&key_func, sizeof(KEY_FUNC), 1, tde_exe );
  160.          fseek( tde_exe, two_key_offset, SEEK_SET );
  161.          fwrite( (void *)&two_key_list, sizeof(TWO_KEY), 1, tde_exe );
  162.          fseek( tde_exe, macro_offset, SEEK_SET );
  163.          fwrite( (void *)¯os, sizeof(MACRO), 1, tde_exe );
  164.          fseek( tde_exe, color_offset, SEEK_SET );
  165.          fwrite( (void *)&temp_colours, sizeof(COLORS), 1, tde_exe );
  166.          fseek( tde_exe, mode_offset, SEEK_SET );
  167.          fwrite( (void *)&in_modes, sizeof( MODE_INFO ), 1, tde_exe );
  168.          fseek( tde_exe, sort_offset, SEEK_SET );
  169.          fwrite( (void *)&sort_order, sizeof( SORT_ORDER ), 1, tde_exe );
  170.          fclose( config );
  171.          printf( "\n\n    Configuration file read.  Press a key to continue :" );
  172.          getkey( );
  173.       }
  174.    }
  175.    cls( );
  176. }
  177.  
  178.  
  179. /*
  180.  * Name:    parse_line
  181.  * Purpose: real work horse of the configuration utility, figure out what
  182.  *          we need to do with each line of the config file.
  183.  * Date:    June 5, 1992
  184.  * Passed:  line:  line that contains the text to parse
  185.  */
  186. void parse_line( char *line )
  187. {
  188. char key[1042];         /* buffer to hold any token that we parse */
  189. char *residue;          /* pointer to next item in line, if it exists */
  190. int key_no;             /* index into key array */
  191. int parent_key;         /* 1st of two-combination keys */
  192. int color;              /* color field */
  193. int mode_index;         /* index in mode array */
  194. int func_no;            /* function number we want to assign to a key */
  195. int color_no;           /* attribute we want to assign to a color field */
  196. int mode_no;            /* mode number we want to assign to a mode */
  197. int found;              /* boolean, did we find a valid key, color, or mode? */
  198. int i;
  199.  
  200.    /*
  201.     * find the first token and put it in key.  residue points to next token.
  202.     */
  203.    residue = parse_token( line, key );
  204.    if (*key != '\0' && *key != ';') {
  205.       if (strlen( key ) > 1) {
  206.          /*
  207.           * try to find a valid key
  208.           */
  209.          found = FALSE;
  210.          key_no = search( key, valid_keys, AVAIL_KEYS-1 );
  211.          if (key_no != ERROR) {
  212.             /*
  213.              * find the function assignment
  214.              */
  215.             found = TRUE;
  216.             if (residue != NULL) {
  217.                residue = parse_token( residue, key );
  218.  
  219.                /*
  220.                 * if this is not a comment, find the function to assign
  221.                 *   to key.  clear any previous macro or key assignment.
  222.                 */
  223.                if (*key != '\0' && *key != ';') {
  224.                   func_no = search( key, valid_func, NUM_FUNC );
  225.                   if (func_no != ERROR) {
  226.                      clear_previous_twokey( key_no );
  227.                      clear_previous_macro( key_no );
  228.                      key_func.key[key_no] = func_no;
  229.                      if (func_no == PlayBack)
  230.                         parse_macro( key_no, residue );
  231.                   } else {
  232.                      parent_key = key_no;
  233.  
  234.                      /*
  235.                       * was the second key one letter?
  236.                       */
  237.                      if (strlen( key ) == 1) {
  238.                         key_no = *key;
  239.                         residue = parse_token( residue, key );
  240.                         if (*key != '\0' && *key != ';') {
  241.                            func_no = search( key, valid_func, NUM_FUNC );
  242.                            if (func_no != ERROR && func_no != PlayBack) {
  243.                               if (insert_twokey( parent_key+256, key_no,
  244.                                                           func_no ) == ERROR) {
  245.                                  printf( "==> %s", line_in );
  246.                                  printf( "Out of room for two-key: line %u  : function %s\n",
  247.                                       line_no, key );
  248.                               }
  249.                            } else {
  250.                               printf( "==> %s", line_in );
  251.                               if ( func_no == ERROR)
  252.                                  printf( "Unrecognized function: line %u  : function %s\n",
  253.                                          line_no, key );
  254.                               else
  255.                                  printf( "Cannot assign a macro to two-keys: line %u  : function %s\n",
  256.                                          line_no, key );
  257.                            }
  258.                         }
  259.                      } else {
  260.                         residue = parse_token( residue, key );
  261.                         key_no = search( key, valid_keys, AVAIL_KEYS-1 );
  262.                         if (key_no != ERROR && *key != '\0' && *key != ';') {
  263.                            func_no = search( key, valid_func, NUM_FUNC );
  264.                            if (func_no != ERROR && func_no != PlayBack) {
  265.                               if (insert_twokey( parent_key+256, key_no+256,
  266.                                                         func_no )  == ERROR) {
  267.                                  printf( "==> %s", line_in );
  268.                                  printf( "Out of room for two-key: line %u  : function %s\n",
  269.                                       line_no, key );
  270.                               }
  271.                            } else {
  272.                               printf( "==> %s", line_in );
  273.                               if ( func_no == ERROR)
  274.                                  printf( "Unrecognized function: line %u  : function %s\n",
  275.                                          line_no, key );
  276.                               else
  277.                                  printf( "Cannot assign a macro to two-keys: line %u  : function %s\n",
  278.                                          line_no, key );
  279.                            }
  280.                         } else {
  281.                            printf( "==> %s", line_in );
  282.                            printf( "Unrecognized function: line %u  : function %s\n",
  283.                                    line_no, key );
  284.                         }
  285.                      }
  286.                   }
  287.                }
  288.             }
  289.          }
  290.  
  291.          /*
  292.           * valid key not found, now try a valid color
  293.           */
  294.          if (!found) {
  295.             color = search( key, valid_colors, (NUM_COLORS * 2) - 1 );
  296.             if (color != ERROR) {
  297.                if (*key == 'm')
  298.                   i = 0;
  299.                else
  300.                   i = 1;
  301.                found = TRUE;
  302.                if (residue != NULL) {
  303.                   residue = parse_token( residue, key );
  304.  
  305.                   /*
  306.                    * we found a color field and attribute.  now, make sure
  307.                    *   everything is everything before we assign the attribute
  308.                    *   to the color field.
  309.                    */
  310.                   if (*key != '\0' && *key != ';') {
  311.                      color_no = atoi( key );
  312.                      if (color_no >= 0 && color_no <= 127)
  313.                         temp_colours.clr[i][color] = color_no;
  314.                      else {
  315.                         printf( "==> %s", line_in );
  316.                         printf( "Color number out of range: line %u  : number %s\n",
  317.                                  line_no, key );
  318.                      }
  319.                   }
  320.                }
  321.             }
  322.          }
  323.  
  324.          /*
  325.           * valid color not found, now try a valid mode
  326.           */
  327.          if (!found) {
  328.             mode_index = search( key, valid_modes, NUM_MODES-1 );
  329.             if (mode_index != ERROR) {
  330.                found = TRUE;
  331.  
  332.                /*
  333.                 * if we find a valid mode, we need to search different
  334.                 *   option arrays before we find a valid assignment.
  335.                 */
  336.                if (residue != NULL) {
  337.                   residue = parse_token( residue, key );
  338.                   if (*key != '\0' && *key != ';') {
  339.                      switch ( mode_index ) {
  340.                         case Ins         :
  341.                         case Ind         :
  342.                         case Smart       :
  343.                         case Trim        :
  344.                         case Eol         :
  345.                         case Backup      :
  346.                         case Ruler       :
  347.                         case InflateTabs :
  348.                         case JustRM      :
  349.                            mode_no = search( key, off_on, 1 );
  350.                            if (mode_no == ERROR) {
  351.                               printf( "==> %s", line_in );
  352.                               printf( "Off/On error: " );
  353.                            }
  354.                            break;
  355.                         case LTAB     :
  356.                         case PTAB     :
  357.                            mode_no = atoi( key );
  358.                            if (mode_no > 520 || mode_no < 1) {
  359.                               mode_no = ERROR;
  360.                               printf( "==> %s", line_in );
  361.                               printf( "Tab error: " );
  362.                            }
  363.                            break;
  364.                         case Left    :
  365.                            mode_no = atoi( key );
  366.                            if (mode_no < 1 || mode_no > modes[Right]) {
  367.                               mode_no = ERROR;
  368.                               printf( "==> %s", line_in );
  369.                               printf( "Left margin error: " );
  370.                            } else
  371.                               --mode_no;
  372.                            break;
  373.                         case Para    :
  374.                            mode_no = atoi( key );
  375.                            if (mode_no < 1 || mode_no > modes[Right]) {
  376.                               mode_no = ERROR;
  377.                               printf( "==> %s", line_in );
  378.                               printf( "Paragraph margin error: " );
  379.                            } else
  380.                               --mode_no;
  381.                            break;
  382.                         case Right   :
  383.                            mode_no = atoi( key );
  384.                            if (mode_no < modes[Left] || mode_no > 1040) {
  385.                               mode_no = ERROR;
  386.                               printf( "==> %s", line_in );
  387.                               printf( "Right margin error: " );
  388.                            } else
  389.                               --mode_no;
  390.                            break;
  391.                         case Crlf    :
  392.                            mode_no = search( key, valid_crlf, 1 );
  393.                            if (mode_no == ERROR) {
  394.                               printf( "==> %s", line_in );
  395.                               printf( "CRLF or LF error: " );
  396.                            }
  397.                            break;
  398.                         case WW      :
  399.                            mode_no = search( key, valid_wraps, 2 );
  400.                            if (mode_no == ERROR) {
  401.                               printf( "==> %s", line_in );
  402.                               printf( "Word wrap error: " );
  403.                            }
  404.                            break;
  405.                         case Size    :
  406.                            mode_no = search( key, valid_cursor, 1 );
  407.                            if (mode_no == ERROR) {
  408.                               printf( "==> %s", line_in );
  409.                               printf( "Cursor size error: " );
  410.                            }
  411.                            break;
  412.                         case Write_Z :
  413.                            mode_no = search( key, valid_z, 1 );
  414.                            if (mode_no == ERROR) {
  415.                               printf( "==> %s", line_in );
  416.                               printf( "Control Z error: " );
  417.                            }
  418.                            break;
  419.                         case Date    :
  420.                            mode_no = search( key, valid_dates, 5 );
  421.                            if (mode_no == ERROR) {
  422.                               printf( "==> %s", line_in );
  423.                               printf( "Date format error: " );
  424.                            }
  425.                            break;
  426.                         case Time    :
  427.                            mode_no = search( key, valid_times, 1 );
  428.                            if (mode_no == ERROR) {
  429.                               printf( "==> %s", line_in );
  430.                               printf( "Time format error: " );
  431.                            }
  432.                            break;
  433.                         case Initcase    :
  434.                            mode_no = search( key, init_case_modes, 1 );
  435.                            if (mode_no == ERROR) {
  436.                               printf( "==> %s", line_in );
  437.                               printf( "Initial Case Mode error: " );
  438.                            }
  439.                            break;
  440.                         case Match   :
  441.                            for (i=0; i<256; i++)
  442.                               sort_order.match[i] = (char)i;
  443.                            new_sort_order( key, sort_order.match );
  444.                            break;
  445.                         case Ignore  :
  446.                            for (i=0; i<256; i++)
  447.                               sort_order.ignore[i] = (char)i;
  448.                            for (i=65; i<91; i++)
  449.                               sort_order.ignore[i] = (char)(i + 32);
  450.                            new_sort_order( key, sort_order.ignore );
  451.                            break;
  452.                      }
  453.                      if (mode_no != ERROR)
  454.                         modes[mode_index] = mode_no;
  455.                      else
  456.                         printf( " line = %u  :  unknown mode = %s\n",
  457.                               line_no, key );
  458.                   }
  459.                }
  460.             }
  461.          }
  462.          if (!found) {
  463.             printf( "==> %s", line_in );
  464.             printf( "Unrecognized editor setting: line %u  :  %s\n", line_no, key );
  465.          }
  466.       }
  467.    }
  468. }
  469.  
  470.  
  471. /*
  472.  * Name:    parse_token
  473.  * Purpose: given an input line, find the first token
  474.  * Date:    June 5, 1992
  475.  * Passed:  line:  line that contains the text to parse
  476.  *          token:   buffer to hold token
  477.  * Returns: pointer in line to start next token search.
  478.  * Notes:   assume tokens are delimited by spaces.
  479.  */
  480. char *parse_token( char *line, char *token )
  481. {
  482.    /*
  483.     * skip over any leading spaces.
  484.     */
  485.    while (*line == ' ')
  486.       ++line;
  487.  
  488.    /*
  489.     * put the characters into the token array until we run into a space
  490.     *   or the terminating '\0';
  491.     */
  492.    while (*line != ' ' && *line != '\0' && *line != '\n')
  493.       *token++ = *line++;
  494.    *token = '\0';
  495.  
  496.    /*
  497.     * return what's left on the line, if anything.
  498.     */
  499.    if (*line != '\0' && *line != '\n')
  500.       return( line );
  501.    else
  502.       return( NULL );
  503. }
  504.  
  505.  
  506. /*
  507.  * Name:    search
  508.  * Purpose: binary search a CONFIG_DEFS structure
  509.  * Date:    June 5, 1992
  510.  * Passed:  token:  token to search for
  511.  *          list:   list of valid tokens
  512.  *          num:    number of valid tokens in list
  513.  * Returns: value of token assigned to matching token.
  514.  * Notes:   do a standard binary search.
  515.  *          instead of returning mid, lets return the value of the token
  516.  *          assigned to mid.
  517.  */
  518. int  search( char *token, CONFIG_DEFS list[], int num )
  519. {
  520. int bot;
  521. int mid;
  522. int top;
  523. int rc;
  524.  
  525.    bot = 0;
  526.    top = num;
  527.    while (bot <= top) {
  528.       mid = (bot + top) / 2;
  529.       rc = stricmp( token, list[mid].key );
  530.       if (rc == 0)
  531.          return( list[mid].key_index );
  532.       else if (rc < 0)
  533.          top = mid - 1;
  534.       else
  535.          bot = mid + 1;
  536.    }
  537.    return( ERROR );
  538. }
  539.  
  540.  
  541. /*
  542.  * Name:    parse_macro
  543.  * Purpose: separate literals from keys in a macro definition
  544.  * Date:    June 5, 1992
  545.  * Passed:  macro_key:  key that we are a assigning a macro to
  546.  *          residue:    pointer to macro defs
  547.  * Notes:   for each token in macro def, find out if it's a literal or a
  548.  *             function key.
  549.  *          a literal begins with a ".  to put a " in a macro def, precede
  550.  *             a " with a ".
  551.  */
  552. void parse_macro( int macro_key, char *residue )
  553. {
  554. int  rc;
  555. char literal[1042];
  556. char *l;
  557. int  key_no;
  558.  
  559.    /*
  560.     * reset any previous macro def.
  561.     */
  562.    initialize_macro( macro_key );
  563.    while (residue != NULL) {
  564.       /*
  565.        * skip over any leading spaces.
  566.        */
  567.       while (*residue == ' ')
  568.          ++residue;
  569.  
  570.       /*
  571.        * done if we hit a comment
  572.        */
  573.       if (*residue == ';')
  574.          residue = NULL;
  575.  
  576.       /*
  577.        * check for a literal.
  578.        */
  579.       else if (*residue == '\"') {
  580.          rc = parse_literal( macro_key, residue, literal, &residue );
  581.          if (rc == OK) {
  582.             l = literal;
  583.             while (*l != '\0'  &&  rc == OK) {
  584.                rc = record_keys( macro_key, *l );
  585.                ++l;
  586.             }
  587.          } else {
  588.             printf( "==> %s", line_in );
  589.             printf( "Literal not recognized: line %u  : literal  %s\n", line_no, literal );
  590.          }
  591.  
  592.       /*
  593.        * check for a function key.
  594.        */
  595.       } else {
  596.          residue = parse_token( residue, literal );
  597.          key_no = search( literal, valid_keys, AVAIL_KEYS );
  598.          if (key_no != ERROR)
  599.             record_keys( macro_key, key_no+256 );
  600.          else {
  601.             printf( "==> %s", line_in );
  602.             printf( "Unrecognized key: line %u  : key %s\n", line_no, literal );
  603.          }
  604.       }
  605.    }
  606.    check_macro( macro_key );
  607. }
  608.  
  609.  
  610. /*
  611.  * Name:    parse_literal
  612.  * Purpose: get all letters in a literal
  613.  * Date:    June 5, 1992
  614.  * Passed:  macro_key:  key that we are a assigning a macro to
  615.  *          line:       current line position
  616.  *          literal:    buffer to hold literal
  617.  *          residue:    pointer to next token in line
  618.  * Notes:   a literal begins with a ".  to put a " in a macro def, precede
  619.  *             a " with a ".
  620.  */
  621. int  parse_literal( int macro_key, char *line, char *literal, char **residue )
  622. {
  623. int quote_state = 1;    /* we've already seen one " before we get here */
  624.  
  625.    line++;
  626.    /*
  627.     * put the characters into the literal array until we run into the
  628.     *   end of literal or terminating '\0';
  629.     */
  630.    while (*line != '\0' && *line != '\n') {
  631.       if (*line != '\"')
  632.          *literal++ = *line++;
  633.       else {
  634.          if (*(line+1) == '\"') {
  635.             *literal++ = '\"';
  636.             line++;
  637.             line++;
  638.          } else {
  639.             line++;
  640.             --quote_state;
  641.             break;
  642.          }
  643.       }
  644.    }
  645.    *literal = '\0';
  646.  
  647.    /*
  648.     * return what's left on the line, if anything.
  649.     */
  650.    if (*line != '\0' && *line != '\n')
  651.       *residue = line;
  652.    else
  653.       *residue = NULL;
  654.    if (quote_state != 0) {
  655.       *residue = NULL;
  656.       return( ERROR );
  657.    } else
  658.       return( OK );
  659. }
  660.  
  661.  
  662. /*
  663.  * Name:    initialize_macro
  664.  * Purpose: initialize the first key of a macro def
  665.  * Date:    June 5, 1992
  666.  * Passed:  macro_key:  key that we are a assigning a macro to
  667.  * Notes:   this function is ported directly from tde.
  668.  */
  669. void initialize_macro( int macro_key )
  670. {
  671. register int next;
  672. int  prev;
  673.  
  674.    next = macros.first_stroke[macro_key];
  675.  
  676.    /*
  677.     * initialize the first key in a macro def
  678.     */
  679.    if (next != STROKE_LIMIT+1) {
  680.       do {
  681.          prev = next;
  682.          next = macros.strokes[next].next;
  683.          macros.strokes[prev].key  = MAX_KEYS+1;
  684.          macros.strokes[prev].next = STROKE_LIMIT+1;
  685.          ++stroke_count;
  686.       } while (next != -1);
  687.    }
  688.  
  689.    /*
  690.     * find the first open space and initialize
  691.     */
  692.    for (next=0; macros.strokes[next].next != STROKE_LIMIT+1;)
  693.       next++;
  694.    macros.first_stroke[macro_key] = next;
  695.    macros.strokes[next].key  = -1;
  696.    macros.strokes[next].next = -1;
  697. }
  698.  
  699.  
  700. /*
  701.  * Name:    clear_previous_macro
  702.  * Purpose: clear any macro previously assigned to a key
  703.  * Date:    June 5, 1992
  704.  * Passed:  macro_key:  key that we are a assigning a macro to
  705.  * Notes:   this function is ported directly from tde.
  706.  */
  707. void clear_previous_macro( int macro_key )
  708. {
  709. register int next;
  710. int prev;
  711.  
  712.    next = macros.first_stroke[macro_key];
  713.  
  714.    /*
  715.     * if key has already been assigned to a macro, clear macro def.
  716.     */
  717.    if (next != STROKE_LIMIT+1) {
  718.       do {
  719.          prev = next;
  720.          next = macros.strokes[next].next;
  721.          macros.strokes[prev].key  = MAX_KEYS+1;
  722.          macros.strokes[prev].next = STROKE_LIMIT+1;
  723.       } while (next != -1);
  724.    }
  725.  
  726.    macros.first_stroke[macro_key] = STROKE_LIMIT+1;
  727. }
  728.  
  729.  
  730. /*
  731.  * Name:    check_macro
  732.  * Purpose: see if macro def has any valid key.  if not, clear macro
  733.  * Date:    June 5, 1992
  734.  * Passed:  macro_key:  key that we are a assigning a macro to
  735.  * Notes:   this function is ported directly from tde.
  736.  */
  737. void check_macro( int macro_key )
  738. {
  739. register int next;
  740. register int key;
  741.  
  742.    /*
  743.     * see if the macro has any keystrokes.  if not, then wipe it out.
  744.     */
  745.    key = macro_key;
  746.    if (key != 0) {
  747.       next = macros.first_stroke[key];
  748.       if (macros.strokes[next].key == -1) {
  749.          macros.strokes[next].key  = MAX_KEYS+1;
  750.          macros.strokes[next].next = STROKE_LIMIT+1;
  751.          macros.first_stroke[key-256] = STROKE_LIMIT+1;
  752.          if (key_func.key[key] == PlayBack)
  753.             key_func.key[key] = 0;
  754.       }
  755.    }
  756. }
  757.  
  758.  
  759. /*
  760.  * Name:    record_keys
  761.  * Purpose: save keystrokes in keystroke buffer
  762.  * Date:    June 5, 1992
  763.  * Passed:  line: line to display prompts
  764.  * Notes:   -1 in .next field indicates the end of a recording
  765.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  766.  *           Recall, return codes are for macros.  Since we do not allow
  767.  *           keys to be assigned to macro functions, let's just return OK;
  768.  */
  769. int  record_keys( int macro_key, int key )
  770. {
  771. register int next;
  772. register int prev;
  773. int func;
  774. int rc;
  775.  
  776.    rc = OK;
  777.    if (stroke_count == 0) {
  778.       printf( "==> %s", line_in );
  779.       printf( "No more room in macro buffer:  line %u\n",
  780.                line_no );
  781.       rc = ERROR;
  782.    } else {
  783.       func = getfunc( key );
  784.       if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
  785.           func != ClearAllMacros) {
  786.  
  787.          /*
  788.           * a -1 in the next field marks the end of the keystroke recording.
  789.           */
  790.          next = macros.first_stroke[macro_key];
  791.          if (macros.strokes[next].next != STROKE_LIMIT+1) {
  792.             while (macros.strokes[next].next != -1)
  793.                next = macros.strokes[next].next;
  794.          }
  795.          prev = next;
  796.  
  797.          /*
  798.           * now find an open space to record the current key.
  799.           */
  800.          if (macros.strokes[next].key != -1) {
  801.             for (; next < STROKE_LIMIT &&
  802.                          macros.strokes[next].next != STROKE_LIMIT+1;)
  803.                next++;
  804.             if (next == STROKE_LIMIT) {
  805.                for (next=0; next < prev &&
  806.                             macros.strokes[next].next != STROKE_LIMIT+1;)
  807.                   next++;
  808.             }
  809.          }
  810.          if (next == prev && macros.strokes[prev].key != -1) {
  811.             rc = ERROR;
  812.          } else {
  813.          /*
  814.           * next == prev if we are recording the initial macro node.
  815.           */
  816.             macros.strokes[prev].next = next;
  817.             macros.strokes[next].next = -1;
  818.             macros.strokes[next].key  = key;
  819.             stroke_count--;
  820.          }
  821.       }
  822.    }
  823.    return( rc );
  824. }
  825.  
  826.  
  827. /*
  828.  * Name:    new_sort_order
  829.  * Purpose: change the sort order
  830.  * Date:    October 31, 1992
  831.  * Notes:   New sort oder starts at the @ sign
  832.  */
  833. void new_sort_order( unsigned char *residue, unsigned char *sort )
  834. {
  835. int i;
  836.  
  837.    sort += 33;
  838.    for (i=33; *residue != '\0'  &&  *residue != '\n' && i <= 255; i++)
  839.       *sort++ = *residue++;
  840. }
  841.  
  842.  
  843. /*
  844.  * Name:    get_stroke_count
  845.  * Purpose: count unassigned nodes in macro buff
  846.  * Date:    June 5, 1992
  847.  * Returns: number of strokes left in macro buffer.
  848.  */
  849. int  get_stroke_count( void )
  850. {
  851. int count = 0;
  852. int i;
  853.  
  854.    for (i=0; i<STROKE_LIMIT; i++)
  855.       if (macros.strokes[i].next == STROKE_LIMIT+1)
  856.          ++count;
  857.    return( count );
  858. }
  859.  
  860.  
  861.  
  862. /*
  863.  * Name:    getfunc
  864.  * Purpose: get the function assigned to key c
  865.  * Date:    June 5, 1992
  866.  * Passed:  c:  key just pressed
  867.  * Notes:   key codes less than 256 or 0x100 are not assigned a function.
  868.  *          The codes in the range 0-255 are ASCII and extended ASCII chars.
  869.  */
  870. int  getfunc( int c )
  871. {
  872. register int i = c;
  873.  
  874.    if (i <= 256)
  875.       i = 0;
  876.    else
  877.       i = key_func.key[i-256];
  878.    return( i );
  879. }
  880.  
  881.  
  882. /*
  883.  * Name:    clear_previous_twokey
  884.  * Purpose: clear any previously assigned two-key combos
  885.  * Date:    April 1, 1993
  886.  * Passed:  macro_key:  key that we are clearing
  887.  */
  888. void clear_previous_twokey( int two_key )
  889. {
  890. int i;
  891.  
  892.    for (i=0; i < MAX_TWO_KEYS; i++) {
  893.       if (two_key == two_key_list.key[i].parent_key) {
  894.          two_key_list.key[i].parent_key = 0;
  895.          two_key_list.key[i].child_key  = 0;
  896.          two_key_list.key[i].func       = 0;
  897.       }
  898.    }
  899. }
  900.  
  901.  
  902. /*
  903.  * Name:    insert_twokey
  904.  * Purpose: find an open slot and insert the new two-key combination
  905.  * Date:    April 1, 1993
  906.  * Passed:  parent_key:  1st key
  907.  *          child_key:   2nd key
  908.  *          func_no:     function number to assign to this combo
  909.  * Notes:   find the first avaible open slot.  clear any previously defined
  910.  *          previous parent-child combo.
  911.  */
  912. int  insert_twokey( int parent_key, int child_key, int func_no )
  913. {
  914. register int i;
  915. int  rc;
  916.  
  917.    for (i=0; i < MAX_TWO_KEYS; i++) {
  918.       if (parent_key == two_key_list.key[i].parent_key) {
  919.          if (child_key == two_key_list.key[i].child_key) {
  920.             two_key_list.key[i].parent_key = 0;
  921.             two_key_list.key[i].child_key  = 0;
  922.             two_key_list.key[i].func       = 0;
  923.          }
  924.       }
  925.    }
  926.    for (i=0; i < MAX_TWO_KEYS; i++) {
  927.       if (two_key_list.key[i].parent_key == 0) {
  928.          two_key_list.key[i].parent_key = parent_key;
  929.          two_key_list.key[i].child_key  = child_key;
  930.          two_key_list.key[i].func       = func_no;
  931.          break;
  932.       }
  933.    }
  934.    rc = OK;
  935.    if (i == MAX_TWO_KEYS)
  936.       rc = ERROR;
  937.    return( rc );
  938. }
  939.